+Tue Apr 25 10:25:28 2006 Søren Sandmann <sandmann@redhat.com>
+
+ * tests/testgtk.c (create_alpha_window): Create 'composited' label.
+
+ * tests/testgtk.c (on_composited_changed): New function, change
+ the label to say whether the screen is composited or not.
+
+ * gtk/gtkwindow.c (gtk_window_on_composited_changed): When
+ composited status change, invalidate the window and propagate the signal;.
+
+ * gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
+ if reset_type_hint is TRUE.
+
+ * gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
+ the old hints, store a shadow copy in the public window->type_hint
+ bitfield, otherwise set this field to normal. Set the private
+ field to the type hint.
+
+ * gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.
+
+ * gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
+ "reset_type_hint" indicating whether the type hint needs to be
+ reset. New field type_hint containing a GdkWindowTypeHint.
+
+ * gtk/gtkwidget.c (propagate_composited_changed): New function to
+ propagate changes in composited status.
+ (gtk_widget_class_init): Add composited_changed signal.
+
+ * gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
+
+ * gtk/gtkwidget.c (gtk_widget_is_composited): New function.
+
+ * gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
+
+ * gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
+
+ * gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
+ the item belongs to a menubar. Set the type_hint appropriately
+ depending on the outcome.
+
+ * gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
+
+ * gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
+ changed on the attach widget.
+
+ * gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
+ set the transient_for property for menus.
+
+ * gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
+
+ * gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
+ transient for the toplevel.
+
+ * gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
+ transient-for, for the popup window.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
+ new window types.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
+ for new window types.
+
+ * gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
+ New function called whenever the compositing manager comes and goes.
+
+ * gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
+
+ * gdk/x11/gdkscreen-x11.c
+ (_gdk_x11_screen_request_cm_notification, make_cm_atom,
+ check_is_composited): New functions
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
+ _gdk_x11_screen_process_owner_change when an
+ XFixesSelectionNotifyEvent is received.
+
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
+ _gdk_x11_screen_request_cm_notification() on all screens.
+
+ * gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
+ implementation.
+
+ * gdk/gdkscreen.c (gdk_screen_class_init): New signal,
+ 'composited-changed'.
+
+ * gdk/gdkwindow.h: Add new EWMH window types.
+
+ * gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)
+
2006-04-25 Matthias Clasen <mclasen@redhat.com>
* modules/printbackends/cups/gtkprintbackendcups.c:
* gtk/gtkprinter.c:
Don't ref the backend since the backend owns the printer.
+>>>>>>> 1.7779
2006-04-24 Alexander Larsson <alexl@redhat.com>
* gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
+Tue Apr 25 10:25:28 2006 Søren Sandmann <sandmann@redhat.com>
+
+ * tests/testgtk.c (create_alpha_window): Create 'composited' label.
+
+ * tests/testgtk.c (on_composited_changed): New function, change
+ the label to say whether the screen is composited or not.
+
+ * gtk/gtkwindow.c (gtk_window_on_composited_changed): When
+ composited status change, invalidate the window and propagate the signal;.
+
+ * gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
+ if reset_type_hint is TRUE.
+
+ * gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
+ the old hints, store a shadow copy in the public window->type_hint
+ bitfield, otherwise set this field to normal. Set the private
+ field to the type hint.
+
+ * gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.
+
+ * gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
+ "reset_type_hint" indicating whether the type hint needs to be
+ reset. New field type_hint containing a GdkWindowTypeHint.
+
+ * gtk/gtkwidget.c (propagate_composited_changed): New function to
+ propagate changes in composited status.
+ (gtk_widget_class_init): Add composited_changed signal.
+
+ * gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
+
+ * gtk/gtkwidget.c (gtk_widget_is_composited): New function.
+
+ * gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
+
+ * gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
+
+ * gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
+ the item belongs to a menubar. Set the type_hint appropriately
+ depending on the outcome.
+
+ * gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
+
+ * gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
+ changed on the attach widget.
+
+ * gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
+ set the transient_for property for menus.
+
+ * gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
+
+ * gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
+ transient for the toplevel.
+
+ * gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
+ transient-for, for the popup window.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
+ new window types.
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
+ for new window types.
+
+ * gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
+ New function called whenever the compositing manager comes and goes.
+
+ * gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
+
+ * gdk/x11/gdkscreen-x11.c
+ (_gdk_x11_screen_request_cm_notification, make_cm_atom,
+ check_is_composited): New functions
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
+ _gdk_x11_screen_process_owner_change when an
+ XFixesSelectionNotifyEvent is received.
+
+ * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
+ _gdk_x11_screen_request_cm_notification() on all screens.
+
+ * gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
+ implementation.
+
+ * gdk/gdkscreen.c (gdk_screen_class_init): New signal,
+ 'composited-changed'.
+
+ * gdk/gdkwindow.h: Add new EWMH window types.
+
+ * gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)
+
2006-04-25 Matthias Clasen <mclasen@redhat.com>
* modules/printbackends/cups/gtkprintbackendcups.c:
* gtk/gtkprinter.c:
Don't ref the backend since the backend owns the printer.
+>>>>>>> 1.7779
2006-04-24 Alexander Larsson <alexl@redhat.com>
* gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
enum
{
SIZE_CHANGED,
+ COMPOSITED_CHANGED,
LAST_SIGNAL
};
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+
+ /**
+ * GdkScreen::composited-changed:
+ * @screen: the object on which the signal is emitted
+ *
+ * The ::composited_changed signal is emitted when the composited
+ * status of the screen changes
+ *
+ * Since: 2.10
+ */
+ signals[COMPOSITED_CHANGED] =
+ g_signal_new (g_intern_static_string ("composited_changed"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdkScreenClass, composited_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
}
static void
GObjectClass parent_class;
void (*size_changed) (GdkScreen *screen);
+ void (*composited_changed) (GdkScreen *screen);
};
GType gdk_screen_get_type (void) G_GNUC_CONST;
GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen);
GdkColormap *gdk_screen_get_rgba_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgba_visual (GdkScreen *screen);
-
+gboolean gdk_screen_is_composited (GdkScreen *screen);
GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);
GdkDisplay * gdk_screen_get_display (GdkScreen *screen);
{
GDK_WINDOW_TYPE_HINT_NORMAL,
GDK_WINDOW_TYPE_HINT_DIALOG,
- GDK_WINDOW_TYPE_HINT_MENU,
+ GDK_WINDOW_TYPE_HINT_MENU, /* Torn off menu */
GDK_WINDOW_TYPE_HINT_TOOLBAR,
GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
GDK_WINDOW_TYPE_HINT_UTILITY,
GDK_WINDOW_TYPE_HINT_DOCK,
- GDK_WINDOW_TYPE_HINT_DESKTOP
+ GDK_WINDOW_TYPE_HINT_DESKTOP,
+ GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU, /* A drop down menu (from a menubar) */
+ GDK_WINDOW_TYPE_HINT_POPUP_MENU, /* A popup menu (from right-click) */
+ GDK_WINDOW_TYPE_HINT_TOOLTIP,
+ GDK_WINDOW_TYPE_HINT_NOTIFICATION,
+ GDK_WINDOW_TYPE_HINT_COMBO,
+ GDK_WINDOW_TYPE_HINT_DND
} GdkWindowTypeHint;
-
/* The next two enumeration values current match the
* Motif constants. If this is changed, the implementation
* of gdk_window_set_decorations/gdk_window_set_functions
return NULL;
}
+
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ return TRUE;
+}
return NULL;
}
+
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ return FALSE;
+}
"WM_LOCALE_NAME",
"WM_PROTOCOLS",
"WM_TAKE_FOCUS",
+ "_NET_WM_CM_S0",
"_NET_WM_DESKTOP",
"_NET_WM_ICON",
"_NET_WM_ICON_NAME",
_gdk_input_init (display);
_gdk_dnd_init (display);
+ for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
+ _gdk_x11_screen_request_cm_notification (display_x11->screens[i]);
+
g_signal_emit_by_name (gdk_display_manager_get(),
"display_opened", display);
*
* Since: 2.6
**/
-gboolean gdk_display_request_selection_notification (GdkDisplay *display,
- GdkAtom selection)
+gboolean
+gdk_display_request_selection_notification (GdkDisplay *display,
+ GdkAtom selection)
{
#ifdef HAVE_XFIXES
if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
{
XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+
+ _gdk_x11_screen_process_owner_change (screen, xevent);
+
event->owner_change.type = GDK_OWNER_CHANGE;
event->owner_change.window = window;
event->owner_change.owner = selection_notify->owner;
selection_notify->selection);
event->owner_change.time = selection_notify->timestamp;
event->owner_change.selection_time = selection_notify->selection_timestamp;
-
+
return_val = TRUE;
}
else
#include <X11/extensions/Xrandr.h>
#endif
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
static void gdk_screen_x11_dispose (GObject *object);
static void gdk_screen_x11_finalize (GObject *object);
static void init_xinerama_support (GdkScreen *screen);
return GDK_SCREEN_X11 (screen)->screen_num;
}
+static gboolean
+check_is_composited (GdkDisplay *display,
+ GdkScreenX11 *screen_x11)
+{
+ Atom xselection = gdk_x11_atom_to_xatom_for_display (display, screen_x11->cm_selection_atom);
+ Window xwindow;
+
+ xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), xselection);
+
+ return xwindow != None;
+}
+
+static GdkAtom
+make_cm_atom (int screen_number)
+{
+ gchar *name = g_strdup_printf ("_NET_WM_CM_S%d", screen_number);
+ GdkAtom atom = gdk_atom_intern (name, FALSE);
+ g_free (name);
+ return atom;
+}
+
GdkScreen *
_gdk_x11_screen_new (GdkDisplay *display,
gint screen_number)
screen_x11->wmspec_check_window = None;
/* we want this to be always non-null */
screen_x11->window_manager_name = g_strdup ("unknown");
+ screen_x11->cm_selection_atom = make_cm_atom (screen_number);
+ screen_x11->is_composited = check_is_composited (display, screen_x11);
init_xinerama_support (screen);
init_randr_support (screen);
_gdk_visual_init (screen);
_gdk_windowing_window_init (screen);
-
+
return screen;
}
+void
+_gdk_x11_screen_request_cm_notification (GdkScreenX11 *screen_x11)
+{
+ gdk_display_request_selection_notification (screen_x11->display, screen_x11->cm_selection_atom);
+}
+
+/**
+ * gdk_screen_is_composited:
+ * @screen: a #GdkScreen
+ *
+ * Returns whether windows with an RGBA visual can reasonably
+ * be expected to have their alpha channel drawn correctly on
+ * the screen.
+ *
+ * On X11 this function returns whether a compositing manager is
+ * compositing @screen.
+ *
+ * Return value: Whether windows with RGBA visuals can reasonably be
+ * expected to have their alpha channels drawn correctly on the screen.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+ GdkScreenX11 *screen_x11;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ screen_x11 = GDK_SCREEN_X11 (screen);
+
+ return screen_x11->is_composited;
+}
+
#ifdef HAVE_XINERAMA
static gboolean
check_solaris_xinerama (GdkScreen *screen)
g_signal_emit (screen, signals[WINDOW_MANAGER_CHANGED], 0);
}
+void
+_gdk_x11_screen_process_owner_change (GdkScreen *screen,
+ XEvent *event)
+{
+ XFixesSelectionNotifyEvent *selection_event = (XFixesSelectionNotifyEvent *)event;
+ GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+ Atom xcm_selection_atom = gdk_x11_atom_to_xatom_for_display (screen_x11->display,
+ screen_x11->cm_selection_atom);
+
+ if (selection_event->selection == xcm_selection_atom)
+ {
+ gboolean composited = selection_event->owner != None;
+
+ if (composited != screen_x11->is_composited)
+ {
+ screen_x11->is_composited = composited;
+
+ g_signal_emit_by_name (screen, "composited_changed");
+ }
+ }
+}
+
/**
* _gdk_windowing_substitute_screen_number:
* @display_name : The name of a display, in the form used by
gint xft_hintstyle;
gint xft_rgba;
gint xft_dpi;
+
+ GdkAtom cm_selection_atom;
+ gboolean is_composited;
};
struct _GdkScreenX11Class
void _gdk_x11_screen_window_manager_changed (GdkScreen *screen);
void _gdk_x11_screen_size_changed (GdkScreen *screen,
XEvent *event);
+void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
+ XEvent *event);
G_END_DECLS
case GDK_WINDOW_TYPE_HINT_DESKTOP:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
break;
+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
+ break;
+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
+ break;
+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
+ break;
+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
+ break;
+ case GDK_WINDOW_TYPE_HINT_COMBO:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
+ break;
+ case GDK_WINDOW_TYPE_HINT_DND:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
+ break;
default:
g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
/* Fall thru */
type = GDK_WINDOW_TYPE_HINT_DOCK;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
type = GDK_WINDOW_TYPE_HINT_DESKTOP;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
+ type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
+ type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
+ type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
+ type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
+ type = GDK_WINDOW_TYPE_HINT_COMBO;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
+ type = GDK_WINDOW_TYPE_HINT_DND;
}
if (type_return != None && data != NULL)
{
gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
GTK_WINDOW (combo->popwin));
+ gtk_window_set_transient_for (combo->popwin, GTK_WINDOW (toplevel));
}
gtk_widget_set_size_request (combo->popwin, width, height);
G_CALLBACK (gtk_combo_popup_button_leave), combo);
combo->popwin = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (combo->popwin), GDK_WINDOW_TYPE_HINT_COMBO);
g_object_ref (combo->popwin);
gtk_window_set_resizable (GTK_WINDOW (combo->popwin), FALSE);
combo_box->priv->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (combo_box->priv->popup_window),
+ GDK_WINDOW_TYPE_HINT_COMBO);
+
g_signal_connect (GTK_WINDOW(combo_box->priv->popup_window),"show",
G_CALLBACK (gtk_combo_box_child_show),
combo_box);
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (combo_box));
if (GTK_IS_WINDOW (toplevel))
- gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
- GTK_WINDOW (combo_box->priv->popup_window));
+ {
+ gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
+ GTK_WINDOW (combo_box->priv->popup_window));
+ gtk_window_set_transient_for (GTK_WINDOW (combo_box->priv->popup_window),
+ GTK_WINDOW (toplevel));
+ }
gtk_window_set_resizable (GTK_WINDOW (combo_box->priv->popup_window), FALSE);
gtk_window_set_screen (GTK_WINDOW (combo_box->priv->popup_window),
/* Push a NULL colormap to guard against gtk_widget_push_colormap() */
gtk_widget_push_colormap (NULL);
window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
set_can_change_screen (window, TRUE);
gtk_widget_pop_colormap ();
gtk_widget_push_colormap (colormap);
window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
set_can_change_screen (window, FALSE);
gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
}
}
+static void
+attach_widget_hierarchy_changed (GtkWidget *attach_widget,
+ GtkWidget *previous_toplevel,
+ gpointer data)
+{
+ GtkMenu *menu = GTK_MENU (data);
+ GtkWidget *new_toplevel = gtk_widget_get_toplevel (attach_widget);
+
+ if (g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen"))
+ {
+ /* If there is an explicit screen set, then don't set WM_TRANSIENT_FOR.
+ * Because, what would happen if the attach widget moved to a different
+ * screen on a different display? The menu wouldn't move along with it,
+ * so we just make it the responsibility of whoever set the screen to
+ * also set WM_TRANSIENT_FOR.
+ */
+ return;
+ }
+
+ if (menu->toplevel && !g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen") &&
+ (!new_toplevel || GTK_IS_WINDOW (new_toplevel)))
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (menu->toplevel),
+ GTK_WINDOW (new_toplevel));
+ }
+}
+
void
gtk_menu_attach_to_widget (GtkMenu *menu,
GtkWidget *attach_widget,
G_CALLBACK (attach_widget_screen_changed), menu);
attach_widget_screen_changed (attach_widget, NULL, menu);
+ g_signal_connect (attach_widget, "hierarchy_changed",
+ G_CALLBACK (attach_widget_hierarchy_changed), menu);
+ attach_widget_hierarchy_changed (attach_widget, NULL, menu);
+
data->detacher = detacher;
g_object_set_data (G_OBJECT (menu), I_(attach_data_key), data);
list = g_object_steal_data (G_OBJECT (attach_widget), ATTACHED_MENUS);
g_signal_handlers_disconnect_by_func (data->attach_widget,
(gpointer) attach_widget_screen_changed,
menu);
+ g_signal_handlers_disconnect_by_func (data->attach_widget,
+ (gpointer) attach_widget_hierarchy_changed,
+ menu);
+ attach_widget_hierarchy_changed (data->attach_widget, NULL, menu);
if (data->detacher)
data->detacher (data->attach_widget, menu);
"app-paintable", TRUE,
NULL);
-
gtk_window_set_type_hint (GTK_WINDOW (menu->tearoff_window),
GDK_WINDOW_TYPE_HINT_MENU);
gtk_window_set_mnemonic_modifier (GTK_WINDOW (menu->tearoff_window), 0);
private->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
private->initially_pushed_in = FALSE;
+
+ /* Set the type hint here to allow custom position functions to set a different hint */
+ if (!GTK_WIDGET_VISIBLE (menu->toplevel))
+ gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
if (menu->position_func)
{
{
GtkMenuItem *menu_item;
GtkWidget *widget;
- GtkWidget *parent_menu_item;
+ GtkMenuItem *parent_menu_item;
GdkScreen *screen;
gint twidth, theight;
gint tx, ty;
ty += widget->allocation.y;
get_offsets (menu, &horizontal_offset, &vertical_offset);
+
+ if (GTK_IS_MENU_BAR (widget->parent))
+ {
+ menu_item->from_menubar = TRUE;
+ }
+ else if (GTK_IS_MENU (widget->parent))
+ {
+ if (GTK_MENU (widget->parent)->parent_menu_item)
+ menu_item->from_menubar = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item)->from_menubar;
+ else
+ menu_item->from_menubar = FALSE;
+ }
+ else
+ {
+ menu_item->from_menubar = FALSE;
+ }
switch (menu_item->submenu_placement)
{
menu_item->submenu_direction = GTK_DIRECTION_LEFT;
tx += widget->allocation.width - twidth;
}
-
if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height)
ty += widget->allocation.height;
else if ((ty - theight) >= monitor.y)
case GTK_LEFT_RIGHT:
if (GTK_IS_MENU (widget->parent))
- parent_menu_item = GTK_MENU (widget->parent)->parent_menu_item;
+ parent_menu_item = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item);
else
parent_menu_item = NULL;
+
parent_xthickness = widget->parent->style->xthickness;
+
if (parent_menu_item && !GTK_MENU (widget->parent)->torn_off)
- menu_item->submenu_direction = GTK_MENU_ITEM (parent_menu_item)->submenu_direction;
- else if (direction == GTK_TEXT_DIR_LTR)
- menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+ {
+ menu_item->submenu_direction = parent_menu_item->submenu_direction;
+ }
else
- menu_item->submenu_direction = GTK_DIRECTION_LEFT;
+ {
+ if (direction == GTK_TEXT_DIR_LTR)
+ menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+ else
+ menu_item->submenu_direction = GTK_DIRECTION_LEFT;
+ }
switch (menu_item->submenu_direction)
{
*y = ty;
gtk_menu_set_monitor (menu, monitor_num);
+
+ if (!GTK_WIDGET_VISIBLE (menu->toplevel))
+ {
+ gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), menu_item->from_menubar?
+ GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU : GDK_WINDOW_TYPE_HINT_POPUP_MENU);
+ }
}
/**
guint submenu_direction : 1;
guint right_justify: 1;
guint timer_from_keypress : 1;
+ guint from_menubar : 1;
guint timer;
};
if (!tooltips->tip_window)
{
tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint (GTK_WINDOW (tooltips->tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
gtk_tooltips_update_screen (tooltips, TRUE);
gtk_widget_set_app_paintable (tooltips->tip_window, TRUE);
gtk_window_set_resizable (GTK_WINDOW (tooltips->tip_window), FALSE);
GdkScreen *pointer_screen;
gint monitor_num, px, py;
GdkRectangle monitor;
+ GtkWindow *toplevel;
if (!tooltips->tip_window)
gtk_tooltips_force_window (tooltips);
else
y = y + widget->allocation.height + 4;
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (toplevel && GTK_IS_WINDOW (toplevel))
+ gtk_window_set_transient_for (tooltips->tip_window, toplevel);
+
gtk_window_move (GTK_WINDOW (tooltips->tip_window), x, y);
gtk_widget_show (tooltips->tip_window);
}
SCREEN_CHANGED,
CAN_ACTIVATE_ACCEL,
GRAB_BROKEN,
+ COMPOSITED_CHANGED,
LAST_SIGNAL
};
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+ widget_signals[COMPOSITED_CHANGED] =
+ g_signal_new (I_("composited_changed"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkWidgetClass, composited_changed),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
/**
* GtkWidget::delete-event:
g_object_unref (widget);
}
+/**
+ * gtk_widget_is_composited:
+ * @widget:
+ *
+ * Whether @widget can rely on having its alpha channel
+ * drawn correctly. On X11 this function returns whether a
+ * compositing manager is running for @widget's screen
+ *
+ * Return value: #TRUE if the widget can rely on its alpha
+ * channel being drawn correctly.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gtk_widget_is_composited (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+
+ return gdk_screen_is_composited (screen);
+}
+
+static void
+propagate_composited_changed (GtkWidget *widget,
+ gpointer dummy)
+{
+ if (GTK_IS_CONTAINER (widget))
+ {
+ gtk_container_forall (GTK_CONTAINER (widget),
+ propagate_composited_changed,
+ NULL);
+ }
+
+ g_signal_emit (widget, widget_signals[COMPOSITED_CHANGED], 0);
+}
+
+void
+_gtk_widget_propagate_composited_changed (GtkWidget *widget)
+{
+ propagate_composited_changed (widget, NULL);
+}
+
/**
* _gtk_widget_propagate_screen_changed:
* @widget: a #GtkWidget
gboolean (*grab_broken_event) (GtkWidget *widget,
GdkEventGrabBroken *event);
+ void (* composited_changed) (GtkWidget *widget);
+
/* Padding for future expansion */
- void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void gtk_widget_set_default_direction (GtkTextDirection dir);
GtkTextDirection gtk_widget_get_default_direction (void);
+/* Compositing manager functionality */
+gboolean gtk_widget_is_composited (GtkWidget *widget);
+
/* Counterpart to gdk_window_shape_combine_mask.
*/
void gtk_widget_shape_combine_mask (GtkWidget *widget,
GtkWidget *previous_toplevel);
void _gtk_widget_propagate_screen_changed (GtkWidget *widget,
GdkScreen *previous_screen);
+void _gtk_widget_propagate_composited_changed (GtkWidget *widget);
GdkColormap* _gtk_widget_peek_colormap (void);
guint accept_focus : 1;
guint focus_on_map : 1;
guint deletable : 1;
+
+ guint reset_type_hint : 1;
+ GdkWindowTypeHint type_hint;
};
static void gtk_window_class_init (GtkWindowClass *klass);
static void gtk_window_notify_keys_changed (GtkWindow *window);
static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
static void gtk_window_free_key_hash (GtkWindow *window);
+static void gtk_window_on_composited_changed (GdkScreen *screen,
+ GtkWindow *window);
static GSList *toplevel_list = NULL;
static GtkBinClass *parent_class = NULL;
priv->accept_focus = TRUE;
priv->focus_on_map = TRUE;
priv->deletable = TRUE;
+ priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
colormap = _gtk_widget_peek_colormap ();
if (colormap)
gtk_decorated_window_init (window);
+ g_signal_connect (window->screen, "composited_changed",
+ G_CALLBACK (gtk_window_on_composited_changed), window);
}
static void
GParamSpec *pspec)
{
GtkWindow *window;
+ GtkWindowPrivate *priv;
window = GTK_WINDOW (object);
-
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
switch (prop_id)
{
GtkWindowGeometryInfo *info;
g_value_set_boolean (value, window->has_toplevel_focus);
break;
case PROP_TYPE_HINT:
- g_value_set_enum (value,
- window->type_hint);
+ g_value_set_enum (value, priv->type_hint);
break;
case PROP_SKIP_TASKBAR_HINT:
g_value_set_boolean (value,
gtk_window_set_type_hint (GtkWindow *window,
GdkWindowTypeHint hint)
{
+ GtkWindowPrivate *priv;
+
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
- window->type_hint = hint;
+
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
+ window->type_hint = hint;
+ else
+ window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+
+ priv->reset_type_hint = TRUE;
+ priv->type_hint = hint;
}
/**
GdkWindowTypeHint
gtk_window_get_type_hint (GtkWindow *window)
{
+ GtkWindowPrivate *priv;
+
g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
- return window->type_hint;
+ priv = GTK_WINDOW_GET_PRIVATE (window);
+
+ return priv->type_hint;
}
/**
window->keys_changed_handler = 0;
}
+ if (window->screen)
+ {
+ g_signal_handlers_disconnect_by_func (window->screen,
+ gtk_window_on_composited_changed, window);
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
window->need_default_size = FALSE;
window->need_default_position = FALSE;
+ if (priv->reset_type_hint)
+ {
+ /* We should only reset the type hint when the application
+ * used gtk_window_set_type_hint() to change the hint.
+ * Some applications use X directly to change the properties;
+ * in that case, we shouldn't overwrite what they did.
+ */
+ gdk_window_set_type_hint (widget->window, priv->type_hint);
+ priv->reset_type_hint = FALSE;
+ }
+
gdk_window_show (widget->window);
if (window->frame)
if (!priv->deletable)
gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
- gdk_window_set_type_hint (widget->window, window->type_hint);
-
+ gdk_window_set_type_hint (widget->window, priv->type_hint);
+
if (gtk_window_get_skip_pager_hint (window))
gdk_window_set_skip_pager_hint (widget->window, TRUE);
window->screen = screen;
gtk_widget_reset_rc_styles (widget);
if (screen != previous_screen)
- _gtk_widget_propagate_screen_changed (widget, previous_screen);
+ {
+ g_signal_handlers_disconnect_by_func (previous_screen,
+ gtk_window_on_composited_changed, window);
+ g_signal_connect (screen, "composited_changed",
+ G_CALLBACK (gtk_window_on_composited_changed), window);
+
+ _gtk_widget_propagate_screen_changed (widget, previous_screen);
+ _gtk_widget_propagate_composited_changed (widget);
+ }
g_object_notify (G_OBJECT (window), "screen");
if (was_mapped)
gtk_widget_map (widget);
}
+static void
+gtk_window_on_composited_changed (GdkScreen *screen,
+ GtkWindow *window)
+{
+ gtk_widget_queue_draw (GTK_WIDGET (window));
+
+ _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
+}
+
static GdkScreen *
gtk_window_check_screen (GtkWindow *window)
{
guint maximize_initially : 1;
guint decorated : 1;
- guint type_hint : 3; /* GdkWindowTypeHint */
+ guint type_hint : 3; /* GdkWindowTypeHint if the hint is one of the original eight. If not, then
+ * it contains GDK_WINDOW_TYPE_HINT_NORMAL
+ */
guint gravity : 5; /* GdkGravity */
guint is_active : 1;
widget->allocation.height / 2,
radius * 1.33);
- if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)))
+ if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) &&
+ gtk_widget_is_composited (widget))
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
else
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
gtk_widget_set_colormap (widget, colormap);
}
+static void
+on_composited_changed (GtkWidget *window,
+ GtkLabel *label)
+{
+ gboolean is_composited = gtk_widget_is_composited (window);
+
+ if (is_composited)
+ gtk_label_set_text (label, "Composited");
+ else
+ gtk_label_set_text (label, "Not composited");
+}
+
void
create_alpha_window (GtkWidget *widget)
{
TRUE, TRUE, 0);
label = gtk_label_new (NULL);
-
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
-
on_alpha_screen_changed (window, NULL, label);
g_signal_connect (window, "screen-changed",
G_CALLBACK (on_alpha_screen_changed), label);
+ label = gtk_label_new (NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+ on_composited_changed (window, GTK_LABEL (label));
+ g_signal_connect (window, "composited_changed", G_CALLBACK (on_composited_changed), label);
+
+ gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
+
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&window);
g_signal_connect (window, "response",
G_CALLBACK (gtk_widget_destroy),
- NULL);
+ NULL);
}
if (!GTK_WIDGET_VISIBLE (window))